import React from 'react';
import {Select as SelectAntd} from 'antd';
import {Icon} from '../index';

import './index.scss';

const keys = ['className', 'style', 'lv', 'data-__field', 'data-__meta']; //多级选择器遍历时需要忽略的key。

/**
 * 选择器：对antd的Select的扩展，支持设置dataSource和默认的后缀图标、filterOption、getPopupContainer
 * 参考：https://ant.design/components/select-cn/
 * 新增属性：
 * dataSource：数据源。类型：object[]。默认值：无。示例：[{label,value,disabled,className}]。
 *    label：标签。类型：string。
 *    value：值。类型：string。
 * renderItem：列表项渲染函数。类型：(item,index) => ReactNode。默认值：见renderItemDefault。
 * 注意：后缀图标的变换通过旋转实现。
 */
export default class Select extends React.Component {
  static Option = SelectAntd.Option;

  static defaultProps = {
    className: '',
    suffixIcon: <Icon type="caret-down" style={{fontSize: '14px'}} />,
    filterOption: (input, option) => option.props.children.toLowerCase().indexOf(input.trim().toLowerCase()) >= 0,
    /**
     * 指定Select的父容器：解决下拉项不随页面滚动的问题。
     */
    getPopupContainer(node) {
      let main = document.getElementsByClassName('content ant-layout-content')[0];
      main.style.position = 'relative';
      return main;
    }
  };

  render() {
    let {className, children, dataSource, renderItem, ...other} = this.props;
    let props = {className: `g-select ${className}`, ...other};
    return (
      <SelectAntd {...props}>
        {this.renderItems()}
        {children}
      </SelectAntd>
    );
  }

  /**
   * 下拉项数组
   */
  renderItems() {
    let {dataSource, renderItem = this.renderItemDefault} = this.props;
    if (dataSource && dataSource.length > 0) return dataSource.map(renderItem);
  }

  /**
   * 下拉项渲染
   */
  renderItemDefault(item = {}, key) {
    let {label} = item;
    let props = {key, title: label, ...item};
    return <SelectAntd.Option {...props}>{label}</SelectAntd.Option>;
  }
}

/**
 * 多级选择器，是对Select的封装，一般用于省市区
 * 参考：https://ant.design/components/select-cn/
 * 新增属性：
 * lv：最大下拉框层级，最小值为1。类型：number。默认值：3。
 * 修改属性：
 * value：下拉框选中的值。类型：string[]。
 * defaultValue：下拉框默认的值。类型：string[]。
 * dataSource：数据源。类型：object[]。示例：[{value,label,children}]。
 * 注意：Select原有的其他属性，现在支持Array类型。
 */
export class Selects extends React.Component {
  static defaultProps = {
    className: '',
    lv: 3
  };

  constructor(props) {
    super(props);
    this.state = {
      valueInner: props.defaultValue || []
    };
    this.isValue = this.initKey(); //父组件是否设置value属性
  }

  render() {
    let {className, style, children} = this.props;
    return (
      <div className={`g-selects ${className}`} style={style}>
        {this.renderSelect()}
        {children}
      </div>
    );
  }

  /**
   * 加载选择器
   */
  renderSelect() {
    this.initDataSource();

    let result = [];
    let status = this.initStatus();
    let {lv} = this.props; //最大下拉框层级
    for (let key in this.props) {
      if (keys.find((item) => item === key)) continue; //过滤Select不需要的属性
      let item = this.props[key];
      for (let i = 0; i < lv; i++) {
        result[i] = result[i] || {};
        if (key === 'value') {
          result[i][key] = status && status[i];
        } else if (key === 'dataSource') {
          result[i][key] = this.dataList[i];
        } else if (key === 'onChange') {
          result[i][key] = (e) => this.onChange(e, i);
        } else if (Array.isArray(item)) {
          result[i][key] = item[i];
        } else {
          result[i][key] = item;
        }
      }
    }
    //需要给Select设置value，否则无法修改Select
    if (!this.isValue) {
      for (let i = 0; i < lv; i++) {
        result[i].value = status && status[i];
      }
    }

    let views = result.map((item, key) => {
      return <Select key={key} {...item} />;
    });

    return views;
  }

  //父组件是否设置指定属性
  initKey(key = 'value') {
    let propsData = this.props; //父组件设置的属性
    let keys = propsData && Object.keys(propsData);
    let isParent = keys && keys.find((i) => i === key); //父组件是否设置指定属性
    return !!isParent;
  }

  /**
   * 获取组件的数据
   */
  initStatus() {
    if (this.isValue) {
      return this.props.value;
    } else {
      return this.state.valueInner;
    }
  }

  /**
   * 初始化数据源
   */
  initDataSource() {
    let status = this.initStatus();
    let {lv, dataSource} = this.props;
    this.dataList = {};
    let list = dataSource;
    for (let i = 0; i < lv; i++) {
      if (!list || list.length === 0) {
        break;
      }
      let childrenList;
      this.dataList[i] = list.map((item) => {
        if (!childrenList) {
          if (status && status[i] === item.value) {
            childrenList = item.children;
          }
        }
        return {value: item.value, label: item.label};
      });
      list = childrenList;
    }
  }

  /**
   * 监听下拉框选事件
   * @param data 选中的值
   * @param key 索引
   */
  onChange(data, key) {
    let status = this.initStatus();
    let {lv, onChange} = this.props;
    let result = [];
    for (let i = 0; i < lv; i++) {
      if (i < key) {
        result[i] = status[i];
      } else if (i === key) {
        result[i] = data;
      } else {
        result[i] = undefined;
      }
    }
    if (!this.isValue) this.setState({valueInner: result});
    onChange && onChange(result);
  }
}
